package com.bblocks.sms.service.impl;

import com.alibaba.fastjson.JSON;
import com.bblocks.common.Constant;
import com.bblocks.config.SmsConfigProperties;
import com.bblocks.enums.CodeTypeEnum;
import com.bblocks.enums.SysEnum;
import com.bblocks.sms.service.SmsCheckCodeService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.dromara.sms4j.provider.enumerate.SupplierType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * <p>Project: bblocks-pro - SmsCheckCodeServiceImpl</p>
 * <p>描述：短信验证码</p>
 *
 * @Author Zhao [125043150@qq.com]
 * @Date 2023/9/15 10:26
 * @Version 1.0
 * @since 8
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class SmsCheckCodeServiceImpl implements SmsCheckCodeService {
    public static final String MODEL = "SMSCHECKCODE";

    private final SmsConfigProperties smsConfigProperties;

    /**
     * 默认有效时间60秒
     */
    private Integer defaultTime = 60;

    @Resource
    RedisTemplate<String, Object> redisTemplate;

    public SysEnum sendCode(@NonNull String phone, @NonNull String msgCode, @NonNull CodeTypeEnum type, Integer time){
        String key = Constant.SYS_PRE+"::"+MODEL+"::"+type.getType()+"::"+phone;
        if(time == null || time<=0)
            time = defaultTime;

        String tempCode = (String)redisTemplate.opsForValue().get(key);
        if(tempCode != null){
            return SysEnum.IDENTIFYING_SENDED;
        }else{
            int ret = sendCodeOnly(phone, msgCode,SupplierType.ALIBABA);
            if(ret != 1){
                log.warn("发送验证码：{} 至：{}，返回失败：{}",msgCode,phone,ret);
                return SysEnum.IDENTIFYING_ERROR;
            }
            redisTemplate.opsForValue().set(key,msgCode,time.longValue(), TimeUnit.SECONDS);
            return SysEnum.SUCCESS;
        }
    }

    public SysEnum chkCode(@NonNull String phone,@NonNull String msgCode,@NonNull CodeTypeEnum type,boolean failCLean){
        String key = Constant.SYS_PRE+"::"+MODEL+"::"+type.getType()+"::"+phone;

        String tempCode = (String)redisTemplate.opsForValue().get(key);
        if(tempCode == null) {//未发验证码或者超时
            return SysEnum.IDENTIFYING_CODE_NONE;
        }

        if(!msgCode.equalsIgnoreCase(tempCode)){
            if(failCLean)
                redisTemplate.delete(key);
            return SysEnum.IDENTIFYING_COMPARE_ERROR;
        }

        redisTemplate.delete(key);
        return SysEnum.SUCCESS;
    }

    /**
     * 纯发
     * @param msgCode
     * @param phone
     * @return 1=成功，0=失败，-1=异常了
     */
    protected int sendCodeOnly(String phone,String msgCode,SupplierType smsChn){
        try{
            if(smsConfigProperties.getFinalFlag() != 1) {
                log.info("模拟发送返回成功！");
                return 1;
            }
            SmsResponse ret = SmsFactory.createSmsBlend(smsChn != null? smsChn:SupplierType.ALIBABA).sendMessage(phone,msgCode);
            if (ret.isSuccess())
                return 1;
            else {
                log.info("发送sms出错：{}", JSON.toJSONString(ret));
                return 0;
            }
        }catch (Exception e){
            log.warn("发送短信异常：",e);
            return -1;
        }
    }

}
